﻿using System;
using System.Reflection;
using System.Xml;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CMS.Web.Engine;
using CMS.Web.Data;

namespace CMS.Web.Controllers
{
    [ActionError(ViewName = "~/Hosts/Shared/Error.cshtml", Enabled = true)]   
    public class WidgetController : Controller
    { 
        private IPagesRepository _pages;

        public WidgetController(IPagesRepository pages)
        {
            _pages = pages;          
        }

        public ActionResult Edit(int? id)
        {
            IWidget widget = _pages.GetWidget(id.Value);

            List<WidgetSettingsEditorModel> model = widget.Settings.GetType().GetProperties()
                .Select(x => new WidgetSettingsEditorModel(x.Name, x.GetValue(widget.Settings, null), (WidgetSettingAttribute)x.GetCustomAttributes(typeof(WidgetSettingAttribute), false).FirstOrDefault()))
                .Where(x => !x.Annotation.IsNull()).ToList();

            return View("~/Hosts/Shared/WidgetEdit.cshtml", new WidgetEditorModel(widget.Model.Prefix, model)); 
        }

        [HttpPost, ValidateInput(false)]
        public ActionResult Edit(int? id, FormCollection form)
        {
            IWidget widget = _pages.GetWidget(id.Value);

            if (!TryUpdateModel((dynamic)widget.Settings, widget.Model.Prefix, form.ToValueProvider()))
                throw new Exception("Невозможно обновить модель {0}.".Args(widget.Settings.GetType()));

            List<WidgetSettingsEditorModel> model = widget.Settings.GetType().GetProperties()
                .Select(x => new WidgetSettingsEditorModel(x.Name, x.GetValue(widget.Settings, null), (WidgetSettingAttribute)x.GetCustomAttributes(typeof(WidgetSettingAttribute), false).FirstOrDefault()))
                .Where(x => !x.Annotation.IsNull()).ToList();

            _pages.UpdateWidget(widget);
            return Content("Настройки обновлены.");         
        }

        public ActionResult Add()
        {            
            IEnumerable<WidgetAttribute> widgetAnnotations = Assembly.GetExecutingAssembly().GetTypes()
                .Select(x => x.GetCustomAttributes(typeof(WidgetAttribute), true)
                .OfType<WidgetAttribute>().FirstOrDefault())
                .Where(x => x != null);

            List<WidgetCategoryModel> widgetCategories = new List<WidgetCategoryModel>();
            int index = 0;

            foreach (WidgetAttribute annotation in widgetAnnotations)
            {
                WidgetCategoryModel category = widgetCategories.SingleOrDefault(x => string.Equals(x.Name, annotation.Category, StringComparison.InvariantCultureIgnoreCase));
                if (category.IsNull())
                {
                    category = new WidgetCategoryModel { Name = annotation.Category };
                    widgetCategories.Add(category);
                }
                category.Widgets.Add(new WidgetCategoryModel.WidgetDetails(annotation.Guid, annotation.Name, annotation.Description, index));
                index++;
            }
            return View("~/Hosts/Shared/WidgetAdd.cshtml", widgetCategories);
        }

        [HttpPost, ValidateInput(false)]
        public ActionResult Add(int? page, string zone, Guid[] guids)
        {
            _pages.AddWidgets(page.Value, zone, guids);
            return Content("Виджеты добавлены.");
        }
        [HttpPost, ValidateInput(false)]
        public ActionResult Delete(int? id)
        {
            _pages.DeleteWidget(id.Value);
            return Content("Виджет удален.");
        }
    }   
}